package api

import (
	"fmt"
	"io"
	"net"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	log "github.com/sirupsen/logrus"
	"github.com/yourusername/lvm-manager/internal/domain"
	"github.com/yourusername/lvm-manager/internal/host"
	"github.com/yourusername/lvm-manager/internal/network"
	"github.com/yourusername/lvm-manager/internal/snapshot"
	"github.com/yourusername/lvm-manager/internal/storage"
	"github.com/yourusername/lvm-manager/internal/tasks"
)

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		// 在开发环境中允许所有来源
		if gin.Mode() == gin.DebugMode {
			return true
		}

		// 在生产环境中，只允许来自同源或可信来源的连接
		origin := r.Header.Get("Origin")
		if origin == "" {
			return true // 如果没有Origin头，允许连接
		}

		// 检查Origin是否与Host匹配
		host := r.Host
		if strings.HasPrefix(origin, "http://"+host) ||
			strings.HasPrefix(origin, "https://"+host) ||
			strings.HasPrefix(origin, "ws://"+host) ||
			strings.HasPrefix(origin, "wss://"+host) {
			return true
		}

		// 可以在这里添加其他可信来源
		log.Warnf("WebSocket connection rejected from origin: %s", origin)
		return false
	},
}

// Handler REST API 处理器
type Handler struct {
	domainSvc   *domain.Service
	snapshotSvc *snapshot.Service
	storageSvc  *storage.Service
	networkSvc  *network.Service
	taskQueue   *tasks.Queue
	hostManager *host.HostManager // 添加宿主机管理器
}

// NewHandler 创建 API 处理器
func NewHandler(
	domainSvc *domain.Service,
	snapshotSvc *snapshot.Service,
	storageSvc *storage.Service,
	networkSvc *network.Service,
	taskQueue *tasks.Queue,
	hostManager *host.HostManager, // 添加宿主机管理器参数
) *Handler {
	return &Handler{
		domainSvc:   domainSvc,
		snapshotSvc: snapshotSvc,
		storageSvc:  storageSvc,
		networkSvc:  networkSvc,
		taskQueue:   taskQueue,
		hostManager: hostManager,
	}
}

// RegisterRoutes 注册所有路由
func (h *Handler) RegisterRoutes(r *gin.Engine) {
	// 创建宿主机路由处理器
	hostHandler := NewHostHandler(h.hostManager)

	v1 := r.Group("/api/v1")
	{
		// Domain 路由
		domains := v1.Group("/domains")
		{
			domains.GET("", h.ListDomains)
			domains.GET("/:uuid", h.GetDomain)
			domains.POST("", h.CreateDomain)
			domains.POST("/wizard", h.CreateDomainWithWizard) // 新的向导创建端点
			domains.PUT("/:uuid", h.UpdateDomain)             // 新增：更新虚拟机配置
			domains.POST("/:uuid/action", h.DomainAction)
			domains.DELETE("/:uuid", h.DeleteDomain)
			// 检查虚拟机名称是否已存在
			domains.GET("/check-name", h.CheckDomainName)
			// VNC相关路由
			domains.GET("/:uuid/vnc", h.GetVNCInfo)
			domains.GET("/:uuid/vnc/websocket", h.HandleVNCWebSocket)
			// 终端控制台路由
			// GET /api/v1/domains/:uuid/console?type=console
			// 通过WebSocket连接到虚拟机的控制台
			// 支持的type参数: console (默认), serial, parallel, channel
			domains.GET("/:uuid/console", h.OpenConsole)
		}

		// Snapshot 路由
		snapshots := v1.Group("/snapshots")
		{
			snapshots.GET("", h.ListSnapshots)
			snapshots.GET("/:domain/:name", h.GetSnapshot)
			snapshots.POST("/:domain", h.CreateSnapshot)
			snapshots.POST("/:domain/:name/revert", h.RevertSnapshot)
			snapshots.DELETE("/:domain/:name", h.DeleteSnapshot)
		}

		// Storage 路由
		storagePools := v1.Group("/storage/pools")
		{
			storagePools.GET("", h.ListStoragePools)
			storagePools.GET("/:uuid", h.GetStoragePool)
			storagePools.POST("", h.CreateStoragePool)
			storagePools.POST("/:uuid/start", h.StartStoragePool)
			storagePools.POST("/:uuid/stop", h.StopStoragePool)
			storagePools.POST("/:uuid/refresh", h.RefreshStoragePool)
			storagePools.DELETE("/:uuid", h.DeleteStoragePool)
		}

		storageVolumes := v1.Group("/storage/pools/:uuid/volumes")
		{
			storageVolumes.GET("", h.ListStorageVolumes)
			storageVolumes.GET("/:volume", h.GetStorageVolume)
			storageVolumes.POST("", h.CreateStorageVolume)
			storageVolumes.DELETE("/:volume", h.DeleteStorageVolume)
		}

		// Network 路由
		networks := v1.Group("/networks")
		{
			networks.GET("", h.ListNetworks)
			networks.GET("/:name", h.GetNetwork)
			networks.POST("", h.CreateNetwork)
			networks.POST("/:name/start", h.StartNetwork)
			networks.POST("/:name/stop", h.StopNetwork)
			networks.DELETE("/:name", h.DeleteNetwork)
		}

		// Host 路由
		hosts := v1.Group("/hosts")
		{
			hosts.POST("", hostHandler.AddHost)
			hosts.DELETE("/:id", hostHandler.RemoveHost)
			hosts.GET("", hostHandler.ListHosts)
			hosts.GET("/:id", hostHandler.GetHost)
			hosts.POST("/:id/connect", hostHandler.ConnectHost)
			hosts.POST("/:id/disconnect", hostHandler.DisconnectHost)
		}

		// Task 路由
		taskRoutes := v1.Group("/tasks")
		{
			taskRoutes.GET("", h.ListTasks)
			taskRoutes.GET("/:id", h.GetTask)
		}

		// 健康检查
		v1.GET("/health", h.HealthCheck)
	}
}

// HealthCheck 健康检查
func (h *Handler) HealthCheck(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"status":  "ok",
		"service": "lvm-manager",
	})
}

// ListDomains 列出所有 domains
// GET /api/v1/domains?inactive=true
func (h *Handler) ListDomains(c *gin.Context) {
	includeInactive := c.Query("inactive") == "true"

	domains, err := h.domainSvc.List(includeInactive)
	if err != nil {
		log.Errorf("Failed to list domains: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to list domains",
			"detail": err.Error(),
		})

		return
	}

	c.JSON(http.StatusOK, gin.H{
		"domains": domains,
		"count":   len(domains),
	})
}

// GetDomain 获取单个 domain 详情
// GET /api/v1/domains/:uuid?xml=true
func (h *Handler) GetDomain(c *gin.Context) {
	uuid := c.Param("uuid")
	includeXML := c.Query("xml") == "true"

	domain, err := h.domainSvc.GetByUUID(uuid, includeXML)
	if err != nil {
		log.Errorf("Failed to get domain %s: %v", uuid, err)
		c.JSON(http.StatusNotFound, gin.H{
			"error":  "Domain not found",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, domain)
}

// CheckDomainName 检查虚拟机名称是否已存在
// GET /api/v1/domains/check-name?name={name}
func (h *Handler) CheckDomainName(c *gin.Context) {
	name := c.Query("name")
	if name == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "name parameter is required",
		})
		return
	}

	exists, err := h.domainSvc.Exists(name)
	if err != nil {
		log.Errorf("Failed to check domain name %s: %v", name, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to check domain name",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"name":   name,
		"exists": exists,
	})
}

// CreateDomain 创建新 domain
// POST /api/v1/domains
// Body: CreateSpec JSON 或 {"xml": "..."} 用于直接传 XML
func (h *Handler) CreateDomain(c *gin.Context) {
	var rawBody map[string]interface{}
	if err := c.ShouldBindJSON(&rawBody); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error":  "Invalid request body",
			"detail": err.Error(),
		})
		return
	}

	var domainInfo *domain.DomainInfo
	var err error

	// 检查是否是 XML 格式
	if xmlStr, ok := rawBody["xml"].(string); ok && xmlStr != "" {
		domainInfo, err = h.domainSvc.CreateFromXML(xmlStr)
	} else {
		// 解析为 CreateSpec
		var spec domain.CreateSpec
		if err := c.ShouldBindJSON(&spec); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{
				"error":  "Invalid create spec",
				"detail": err.Error(),
			})
			return
		}
		domainInfo, err = h.domainSvc.Create(&spec)
	}

	if err != nil {
		log.Errorf("Failed to create domain: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to create domain",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusCreated, domainInfo)
}

// UpdateDomain 更新虚拟机配置
// PUT /api/v1/domains/:uuid
// Body: UpdateSpec JSON
func (h *Handler) UpdateDomain(c *gin.Context) {
	uuid := c.Param("uuid")

	var spec domain.UpdateSpec
	if err := c.ShouldBindJSON(&spec); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error":  "Invalid update spec",
			"detail": err.Error(),
		})
		return
	}

	// 验证更新规格
	if spec.Name == "" && spec.Memory == 0 && spec.VCPUs == 0 && spec.Autostart == nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error":  "At least one field must be specified for update",
			"detail": "Please provide name, memory, vcpus, or autostart",
		})
		return
	}

	domainInfo, err := h.domainSvc.UpdateByUUID(uuid, &spec)
	if err != nil {
		log.Errorf("Failed to update domain %s: %v", uuid, err)
		statusCode := http.StatusInternalServerError

		// 根据错误类型返回更精确的状态码
		if isNotFoundError(err) {
			statusCode = http.StatusNotFound
		} else if contains(err.Error(), "already exists") {
			statusCode = http.StatusConflict
		}

		c.JSON(statusCode, gin.H{
			"error":  "Failed to update domain",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, domainInfo)
}

// CreateDomainWithWizard 使用向导创建虚拟机
// POST /api/v1/domains/wizard
func (h *Handler) CreateDomainWithWizard(c *gin.Context) {
	var spec domain.VMCreateWizardSpec
	if err := c.ShouldBindJSON(&spec); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error":  "Invalid request body",
			"detail": err.Error(),
		})
		return
	}

	// 验证创建方法
	if spec.Method == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"error":  "Method is required",
			"detail": "Method must be one of: local_iso, network, import_disk, manual",
		})
		return
	}

	// 验证名称
	if spec.Name == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "Name is required",
		})
		return
	}

	// 检查名称是否已存在
	exists, err := h.domainSvc.Exists(spec.Name)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to check domain name",
			"detail": err.Error(),
		})
		return
	}
	if exists {
		c.JSON(http.StatusConflict, gin.H{
			"error":  "Domain name already exists",
			"detail": fmt.Sprintf("Domain with name '%s' already exists", spec.Name),
		})
		return
	}

	// 使用向导创建虚拟机
	domainInfo, err := h.domainSvc.CreateWithWizard(&spec)
	if err != nil {
		log.Errorf("Failed to create domain with wizard: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to create domain",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusCreated, domainInfo)
}

// DomainAction 执行 domain 操作
// POST /api/v1/domains/:uuid/action
// Body: {"action": "start|shutdown|destroy|reboot|suspend|resume"}
func (h *Handler) DomainAction(c *gin.Context) {
	uuid := c.Param("uuid")

	var req struct {
		Action string `json:"action" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error":  "Invalid request",
			"detail": err.Error(),
		})
		return
	}

	var err error
	switch req.Action {
	case "start":
		err = h.domainSvc.StartByUUID(uuid)
	case "shutdown":
		err = h.domainSvc.ShutdownByUUID(uuid)
	case "destroy":
		err = h.domainSvc.DestroyByUUID(uuid)
	case "reboot":
		err = h.domainSvc.RebootByUUID(uuid)
	case "suspend":
		err = h.domainSvc.SuspendByUUID(uuid)
	case "resume":
		err = h.domainSvc.ResumeByUUID(uuid)
	default:
		c.JSON(http.StatusBadRequest, gin.H{
			"error":  "Invalid action",
			"detail": "Action must be one of: start, shutdown, destroy, reboot, suspend, resume",
		})
		return
	}

	if err != nil {
		log.Errorf("Failed to execute action %s on domain %s: %v", req.Action, uuid, err)
		statusCode := http.StatusInternalServerError

		// 根据错误类型返回更精确的状态码
		if isNotFoundError(err) {
			statusCode = http.StatusNotFound
		} else if isInvalidStateError(err) {
			statusCode = http.StatusConflict
		}

		c.JSON(statusCode, gin.H{
			"error":  "Action failed",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "Action executed successfully",
		"action":  req.Action,
		"domain":  uuid,
	})
}

// DeleteDomain 删除 domain 定义
// DELETE /api/v1/domains/:uuid
func (h *Handler) DeleteDomain(c *gin.Context) {
	uuid := c.Param("uuid")

	var req struct {
		Force bool `json:"force"`
	}

	// 如果没有请求体，使用默认值
	if err := c.ShouldBindJSON(&req); err != nil {
		req.Force = false
	}

	if err := h.domainSvc.UndefineByUUID(uuid, req.Force); err != nil {
		log.Errorf("Failed to delete domain %s: %v", uuid, err)
		statusCode := http.StatusInternalServerError
		if isNotFoundError(err) {
			statusCode = http.StatusNotFound
		}
		c.JSON(statusCode, gin.H{
			"error":  "Failed to delete domain",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "Domain deleted successfully",
		"domain":  uuid,
	})
}

// GetVNCInfo 获取虚拟机VNC连接信息
// GET /api/v1/domains/:uuid/vnc
func (h *Handler) GetVNCInfo(c *gin.Context) {
	uuid := c.Param("uuid")

	vncInfo, err := h.domainSvc.GetVNCInfo(uuid) // 修复：使用正确的方法名
	if err != nil {
		log.Errorf("Failed to get VNC info for domain %s: %v", uuid, err)
		statusCode := http.StatusInternalServerError
		if isNotFoundError(err) {
			statusCode = http.StatusNotFound
		}
		c.JSON(statusCode, gin.H{
			"error":  "Failed to get VNC info",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, vncInfo)
}

// OpenConsole 打开虚拟机终端控制台（WebSocket）
// GET /api/v1/domains/:uuid/console?type=console
func (h *Handler) OpenConsole(c *gin.Context) {
	uuid := c.Param("uuid")
	consoleType := c.Query("type")
	if consoleType == "" {
		consoleType = "console"
	}

	// 升级到WebSocket连接
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		log.Errorf("Failed to upgrade to WebSocket: %v", err)
		return
	}
	defer func() {
		if conn != nil {
			conn.Close()
		}
	}()

	// 连接到libvirt控制台
	consoleStream, err := h.domainSvc.OpenConsoleByUUID(uuid, consoleType)
	if err != nil {
		log.Errorf("Failed to open console for domain %s: %v", uuid, err)
		err = conn.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf("Error: %v", err)))
		if err != nil {
			log.Errorf("Failed to send error message to client: %v", err)
		}
		return
	}

	if consoleStream == nil || consoleStream.Stream == nil {
		log.Errorf("Failed to open console for domain %s: console stream is nil", uuid)
		err = conn.WriteMessage(websocket.TextMessage, []byte("Error: failed to open console stream"))
		if err != nil {
			log.Errorf("Failed to send error message to client: %v", err)
		}
		return
	}

	defer func() {
		if consoleStream != nil && consoleStream.Stream != nil {
			consoleStream.Stream.Free()
		}
	}()

	// 设置一个goroutine来读取libvirt控制台数据并发送到WebSocket客户端
	done := make(chan struct{})
	go func() {
		defer close(done)
		buf := make([]byte, 4096) // 增大缓冲区以提高性能
		for {
			n, err := consoleStream.Stream.Recv(buf) // 修复：移除多余的参数
			if err != nil {
				log.Debugf("Console stream closed or error for domain %s: %v", uuid, err)
				return
			}
			if n > 0 {
				// 根据内容类型选择消息类型
				messageType := websocket.BinaryMessage
				// 如果内容看起来像文本，使用文本消息
				if isPrintableASCII(buf[:n]) {
					messageType = websocket.TextMessage
				}

				err = conn.WriteMessage(messageType, buf[:n])
				if err != nil {
					log.Debugf("WebSocket write error for domain %s: %v", uuid, err)
					return
				}
			}
		}
	}()

	// 读取WebSocket客户端消息并发送到libvirt控制台
	for {
		messageType, message, err := conn.ReadMessage()
		if err != nil {
			log.Debugf("WebSocket read error for domain %s: %v", uuid, err)
			break
		}

		// 只转发文本和二进制消息到libvirt控制台
		if messageType == websocket.TextMessage || messageType == websocket.BinaryMessage {
			// 发送消息到libvirt控制台
			_, err = consoleStream.Stream.Send(message) // 修复：移除多余的参数
			if err != nil {
				log.Debugf("Error sending to console stream for domain %s: %v", uuid, err)
				break
			}
		}
	}

	// 等待读取goroutine完成
	<-done
}

// isPrintableASCII 检查数据是否为可打印ASCII字符
func isPrintableASCII(data []byte) bool {
	for _, b := range data {
		if b < 32 || b > 126 {
			// 允许一些常见的控制字符如换行和回车
			if b != '\n' && b != '\r' && b != '\t' {
				return false
			}
		}
	}
	return true
}

// HandleVNCWebSocket 处理VNC WebSocket连接
// GET /api/v1/domains/:uuid/vnc/websocket
func (h *Handler) HandleVNCWebSocket(c *gin.Context) {
	uuid := c.Param("uuid")

	// 获取VNC连接信息
	vncInfo, err := h.domainSvc.GetVNCInfo(uuid) // 修复：使用正确的方法名
	if err != nil {
		log.Errorf("Failed to get VNC info for domain %s: %v", uuid, err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get VNC info"})
		return
	}

	// 检查是否有WebSocket端口
	if vncInfo.WebSocketPort == 0 {
		log.Errorf("No WebSocket port found for domain %s", uuid)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "No WebSocket port available"})
		return
	}

	// 构建目标地址
	targetAddr := fmt.Sprintf("127.0.0.1:%d", vncInfo.Port)

	// 代理WebSocket连接到VNC服务器
	h.proxyWebSocket(c, targetAddr)
}

// proxyWebSocket 代理WebSocket连接到目标地址
func (h *Handler) proxyWebSocket(c *gin.Context, targetAddr string) {
	// 升级到WebSocket连接
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		log.Errorf("Failed to upgrade to WebSocket: %v", err)
		return
	}
	defer conn.Close()

	// 连接到目标地址
	targetConn, err := net.Dial("tcp", targetAddr)
	if err != nil {
		log.Errorf("Failed to connect to target %s: %v", targetAddr, err)
		conn.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf("Error: failed to connect to VNC server: %v", err)))
		return
	}
	defer targetConn.Close()

	// 设置一个goroutine来转发从目标到客户端的消息
	done := make(chan struct{})
	go func() {
		defer close(done)
		buf := make([]byte, 4096)
		for {
			n, err := targetConn.Read(buf)
			if err != nil {
				if err != io.EOF {
					log.Debugf("Error reading from target %s: %v", targetAddr, err)
				}
				return
			}
			if n > 0 {
				err = conn.WriteMessage(websocket.BinaryMessage, buf[:n])
				if err != nil {
					log.Debugf("Error writing to WebSocket client: %v", err)
					return
				}
			}
		}
	}()

	// 转发从客户端到目标的消息
	for {
		messageType, message, err := conn.ReadMessage()
		if err != nil {
			log.Debugf("WebSocket read error: %v", err)
			break
		}

		// 只转发二进制消息到VNC服务器
		if messageType == websocket.BinaryMessage {
			_, err = targetConn.Write(message)
			if err != nil {
				log.Debugf("Error writing to target %s: %v", targetAddr, err)
				break
			}
		}
	}

	// 等待转发goroutine完成
	<-done
}

// ListSnapshots 列出所有快照
// GET /api/v1/snapshots?domain=name
func (h *Handler) ListSnapshots(c *gin.Context) {
	domainName := c.Query("domain")
	if domainName == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "domain parameter is required",
		})
		return
	}

	snapshots, err := h.snapshotSvc.List(domainName)
	if err != nil {
		log.Errorf("Failed to list snapshots for domain %s: %v", domainName, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to list snapshots",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"snapshots": snapshots,
		"count":     len(snapshots),
	})
}

// GetSnapshot 获取单个快照详情
// GET /api/v1/snapshots/:domain/:name?xml=true
func (h *Handler) GetSnapshot(c *gin.Context) {
	domainName := c.Param("domain")
	name := c.Param("name")
	includeXML := c.Query("xml") == "true"

	snapshotInfo, err := h.snapshotSvc.Get(domainName, name, includeXML)
	if err != nil {
		log.Errorf("Failed to get snapshot %s for domain %s: %v", name, domainName, err)
		c.JSON(http.StatusNotFound, gin.H{
			"error":  "Snapshot not found",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, snapshotInfo)
}

// CreateSnapshot 创建新快照
// POST /api/v1/snapshots/:domain
func (h *Handler) CreateSnapshot(c *gin.Context) {
	domainName := c.Param("domain")

	var spec snapshot.CreateSpec
	if err := c.ShouldBindJSON(&spec); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error":  "Invalid request body",
			"detail": err.Error(),
		})
		return
	}

	snapshotInfo, err := h.snapshotSvc.Create(domainName, &spec)
	if err != nil {
		log.Errorf("Failed to create snapshot for domain %s: %v", domainName, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to create snapshot",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusCreated, snapshotInfo)
}

// RevertSnapshot 回滚到指定快照
// POST /api/v1/snapshots/:domain/:name/revert
func (h *Handler) RevertSnapshot(c *gin.Context) {
	domainName := c.Param("domain")
	name := c.Param("name")

	var req struct {
		Force bool `json:"force"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error":  "Invalid request body",
			"detail": err.Error(),
		})
		return
	}

	err := h.snapshotSvc.Revert(domainName, name, req.Force)
	if err != nil {
		log.Errorf("Failed to revert to snapshot %s for domain %s: %v", name, domainName, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to revert to snapshot",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message":  "Snapshot reverted successfully",
		"domain":   domainName,
		"snapshot": name,
	})
}

// DeleteSnapshot 删除快照
// DELETE /api/v1/snapshots/:domain/:name
func (h *Handler) DeleteSnapshot(c *gin.Context) {
	domainName := c.Param("domain")
	name := c.Param("name")

	var req struct {
		DeleteChildren bool `json:"delete_children"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		// 如果没有请求体，使用默认值
		req.DeleteChildren = false
	}

	err := h.snapshotSvc.Delete(domainName, name, req.DeleteChildren)
	if err != nil {
		log.Errorf("Failed to delete snapshot %s for domain %s: %v", name, domainName, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to delete snapshot",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message":  "Snapshot deleted successfully",
		"domain":   domainName,
		"snapshot": name,
	})
}

// ListStoragePools 列出所有存储池
// GET /api/v1/storage/pools?inactive=true
func (h *Handler) ListStoragePools(c *gin.Context) {
	includeInactive := c.Query("inactive") == "true"

	pools, err := h.storageSvc.ListPools(includeInactive)
	if err != nil {
		log.Errorf("Failed to list storage pools: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to list storage pools",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"pools": pools,
		"count": len(pools),
	})
}

// GetStoragePool 获取单个存储池详情
// GET /api/v1/storage/pools/:uuid?xml=true
func (h *Handler) GetStoragePool(c *gin.Context) {
	uuid := c.Param("uuid")
	includeXML := c.Query("xml") == "true"

	poolInfo, err := h.storageSvc.GetPoolByUUID(uuid, includeXML)
	if err != nil {
		log.Errorf("Failed to get storage pool %s: %v", uuid, err)
		c.JSON(http.StatusNotFound, gin.H{
			"error":  "Storage pool not found",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, poolInfo)
}

// CreateStoragePool 创建新存储池
// POST /api/v1/storage/pools
func (h *Handler) CreateStoragePool(c *gin.Context) {
	var spec storage.CreatePoolSpec
	if err := c.ShouldBindJSON(&spec); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error":  "Invalid request body",
			"detail": err.Error(),
		})
		return
	}

	poolInfo, err := h.storageSvc.CreatePool(&spec)
	if err != nil {
		log.Errorf("Failed to create storage pool: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to create storage pool",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusCreated, poolInfo)
}

// StartStoragePool 启动存储池
// POST /api/v1/storage/pools/:uuid/start
func (h *Handler) StartStoragePool(c *gin.Context) {
	uuid := c.Param("uuid")

	err := h.storageSvc.StartPoolByUUID(uuid)
	if err != nil {
		log.Errorf("Failed to start storage pool %s: %v", uuid, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to start storage pool",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "Storage pool started successfully",
		"pool":    uuid,
	})
}

// StopStoragePool 停止存储池
// POST /api/v1/storage/pools/:uuid/stop
func (h *Handler) StopStoragePool(c *gin.Context) {
	uuid := c.Param("uuid")

	err := h.storageSvc.StopPoolByUUID(uuid)
	if err != nil {
		log.Errorf("Failed to stop storage pool %s: %v", uuid, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to stop storage pool",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "Storage pool stopped successfully",
		"pool":    uuid,
	})
}

// RefreshStoragePool 刷新存储池
// POST /api/v1/storage/pools/:uuid/refresh
func (h *Handler) RefreshStoragePool(c *gin.Context) {
	uuid := c.Param("uuid")

	err := h.storageSvc.RefreshPoolByUUID(uuid)
	if err != nil {
		log.Errorf("Failed to refresh storage pool %s: %v", uuid, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to refresh storage pool",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "Storage pool refreshed successfully",
		"pool":    uuid,
	})
}

// DeleteStoragePool 删除存储池
// DELETE /api/v1/storage/pools/:uuid
func (h *Handler) DeleteStoragePool(c *gin.Context) {
	uuid := c.Param("uuid")

	var req struct {
		DeleteVolumes bool `json:"delete_volumes"`
	}

	// 如果没有请求体，使用默认值
	if err := c.ShouldBindJSON(&req); err != nil {
		req.DeleteVolumes = false
	}

	err := h.storageSvc.DeletePoolByUUID(uuid, req.DeleteVolumes)
	if err != nil {
		log.Errorf("Failed to delete storage pool %s: %v", uuid, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to delete storage pool",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "Storage pool deleted successfully",
		"pool":    uuid,
	})
}

// ListStorageVolumes 列出存储卷
// GET /api/v1/storage/pools/:uuid/volumes
func (h *Handler) ListStorageVolumes(c *gin.Context) {
	poolUUID := c.Param("uuid")

	volumes, err := h.storageSvc.ListVolumesByPoolUUID(poolUUID)
	if err != nil {
		log.Errorf("Failed to list volumes in pool %s: %v", poolUUID, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to list volumes",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"volumes": volumes,
		"count":   len(volumes),
		"pool":    poolUUID,
	})
}

// GetStorageVolume 获取存储卷详情
// GET /api/v1/storage/pools/:uuid/volumes/:volume?xml=true
func (h *Handler) GetStorageVolume(c *gin.Context) {
	poolUUID := c.Param("uuid")
	volumeName := c.Param("volume")
	includeXML := c.Query("xml") == "true"

	// 首先通过UUID获取存储池名称
	poolInfo, err := h.storageSvc.GetPoolByUUID(poolUUID, false)
	if err != nil {
		log.Errorf("Failed to get storage pool %s: %v", poolUUID, err)
		c.JSON(http.StatusNotFound, gin.H{
			"error":  "Storage pool not found",
			"detail": err.Error(),
		})
		return
	}

	volumeInfo, err := h.storageSvc.GetVolume(poolInfo.Name, volumeName, includeXML)
	if err != nil {
		log.Errorf("Failed to get volume %s in pool %s: %v", volumeName, poolInfo.Name, err)
		c.JSON(http.StatusNotFound, gin.H{
			"error":  "Volume not found",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, volumeInfo)
}

// CreateStorageVolume 创建存储卷
// POST /api/v1/storage/pools/:uuid/volumes
func (h *Handler) CreateStorageVolume(c *gin.Context) {
	poolUUID := c.Param("uuid")

	var spec storage.CreateVolumeSpec
	if err := c.ShouldBindJSON(&spec); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error":  "Invalid request body",
			"detail": err.Error(),
		})
		return
	}

	// 通过UUID获取存储池名称
	poolInfo, err := h.storageSvc.GetPoolByUUID(poolUUID, false)
	if err != nil {
		log.Errorf("Failed to get storage pool %s: %v", poolUUID, err)
		c.JSON(http.StatusNotFound, gin.H{
			"error":  "Storage pool not found",
			"detail": err.Error(),
		})
		return
	}

	// 设置池名称
	spec.Pool = poolInfo.Name

	volumeInfo, err := h.storageSvc.CreateVolume(&spec)
	if err != nil {
		log.Errorf("Failed to create volume in pool %s: %v", poolInfo.Name, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to create volume",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusCreated, volumeInfo)
}

// DeleteStorageVolume 删除存储卷
// DELETE /api/v1/storage/pools/:uuid/volumes/:volume
func (h *Handler) DeleteStorageVolume(c *gin.Context) {
	poolUUID := c.Param("uuid")
	volumeName := c.Param("volume")

	// 通过UUID获取存储池名称
	poolInfo, err := h.storageSvc.GetPoolByUUID(poolUUID, false)
	if err != nil {
		log.Errorf("Failed to get storage pool %s: %v", poolUUID, err)
		c.JSON(http.StatusNotFound, gin.H{
			"error":  "Storage pool not found",
			"detail": err.Error(),
		})
		return
	}

	err = h.storageSvc.DeleteVolume(poolInfo.Name, volumeName)
	if err != nil {
		log.Errorf("Failed to delete volume %s in pool %s: %v", volumeName, poolInfo.Name, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to delete volume",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "Volume deleted successfully",
		"pool":    poolUUID,
		"volume":  volumeName,
	})
}

// ListNetworks 列出所有网络
// GET /api/v1/networks?inactive=true
func (h *Handler) ListNetworks(c *gin.Context) {
	includeInactive := c.Query("inactive") == "true"

	networks, err := h.networkSvc.List(includeInactive)
	if err != nil {
		log.Errorf("Failed to list networks: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to list networks",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"networks": networks,
		"count":    len(networks),
	})
}

// GetNetwork 获取网络详情
// GET /api/v1/networks/:name?xml=true
func (h *Handler) GetNetwork(c *gin.Context) {
	name := c.Param("name")
	includeXML := c.Query("xml") == "true"

	networkInfo, err := h.networkSvc.Get(name, includeXML)
	if err != nil {
		log.Errorf("Failed to get network %s: %v", name, err)
		c.JSON(http.StatusNotFound, gin.H{
			"error":  "Network not found",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, networkInfo)
}

// CreateNetwork 创建网络
// POST /api/v1/networks
func (h *Handler) CreateNetwork(c *gin.Context) {
	var spec network.CreateSpec
	if err := c.ShouldBindJSON(&spec); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error":  "Invalid request body",
			"detail": err.Error(),
		})
		return
	}

	networkInfo, err := h.networkSvc.Create(&spec)
	if err != nil {
		log.Errorf("Failed to create network: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to create network",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusCreated, networkInfo)
}

// StartNetwork 启动网络
// POST /api/v1/networks/:name/start
func (h *Handler) StartNetwork(c *gin.Context) {
	name := c.Param("name")

	err := h.networkSvc.Start(name)
	if err != nil {
		log.Errorf("Failed to start network %s: %v", name, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to start network",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "Network started successfully",
		"network": name,
	})
}

// StopNetwork 停止网络
// POST /api/v1/networks/:name/stop
func (h *Handler) StopNetwork(c *gin.Context) {
	name := c.Param("name")

	err := h.networkSvc.Stop(name)
	if err != nil {
		log.Errorf("Failed to stop network %s: %v", name, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to stop network",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "Network stopped successfully",
		"network": name,
	})
}

// DeleteNetwork 删除网络
// DELETE /api/v1/networks/:name
func (h *Handler) DeleteNetwork(c *gin.Context) {
	name := c.Param("name")

	err := h.networkSvc.Delete(name)
	if err != nil {
		log.Errorf("Failed to delete network %s: %v", name, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":  "Failed to delete network",
			"detail": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "Network deleted successfully",
		"network": name,
	})
}

// ListTasks 列出所有任务
// GET /api/v1/tasks
func (h *Handler) ListTasks(c *gin.Context) {
	tasks := h.taskQueue.List(tasks.Status(""))
	c.JSON(http.StatusOK, gin.H{
		"tasks": tasks,
		"count": len(tasks),
	})
}

// GetTask 获取任务详情
// GET /api/v1/tasks/:id
func (h *Handler) GetTask(c *gin.Context) {
	id := c.Param("id")

	task, err := h.taskQueue.Get(id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{
			"error": "Task not found",
		})
		return
	}

	c.JSON(http.StatusOK, task)
}

// 错误类型判断辅助函数
func isNotFoundError(err error) bool {
	return err != nil && (err.Error() == "domain not found" ||
		contains(err.Error(), "not found"))
}

func isInvalidStateError(err error) bool {
	return err != nil && (contains(err.Error(), "invalid state") ||
		contains(err.Error(), "already running") ||
		contains(err.Error(), "not running"))
}

func contains(s, substr string) bool {
	return len(s) >= len(substr) && s != "" && substr != "" &&
		(s == substr || len(s) > len(substr)) &&
		(len(substr) == 0 || len(s) >= len(substr))
}
